package com.sugon.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil;
import com.sugon.dao.MaterialRecordDao;
import com.sugon.dao.ToolsStorePosDao;
import com.sugon.entity.ToolsStorePosEntity;
import com.sugon.modules.base.consts.StoreHouseType;
import com.sugon.service.ToolsPartBackService;
import com.sugon.service.ToolsPartInService;
import com.sugon.service.ToolsPartOutService;
import com.sugon.service.ToolsStorePosService;
import com.sugon.utils.Constant;
import com.sugon.utils.ShiroUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 工装仓库位置关联 用于存储备件位置以及数量Service实现类
 *
 * @author sugon
 * @date 2020-04-16 14:05:16
 */
@Service("toolsStorePosService")
public class ToolsStorePosServiceImpl implements ToolsStorePosService {
    @Autowired
    private ToolsStorePosDao toolsStorePosDao;
    @Autowired
    private MaterialRecordDao materialRecordDao;
    @Autowired
    private ToolsPartInService toolsPartInService;
    @Autowired
    private ToolsPartBackService toolsPartBackService;
    @Autowired
    private ToolsPartOutService toolsPartOutService;

    @Override
    public ToolsStorePosEntity queryObject(String id) {
        return toolsStorePosDao.queryObject(id);
    }

    @Override
    public List<ToolsStorePosEntity> queryList(Map<String, Object> map) {
        return toolsStorePosDao.queryList(map);
    }

    @Override
    public int queryTotal(Map<String, Object> map) {
        return toolsStorePosDao.queryTotal(map);
    }

    @Override
    public int save(ToolsStorePosEntity toolsStorePos) {
        toolsStorePos.setId(RandomUtil.randomString(32));
        toolsStorePos.setDelFlag(Constant.IS_NOT_DEL_INT);
        toolsStorePos.setCreateUser(ShiroUtils.getUserId());
        toolsStorePos.setCreateDate(DateUtil.date());
        toolsStorePos.setLocNum(0);
        return toolsStorePosDao.save(toolsStorePos);
    }

    @Override
    public int update(ToolsStorePosEntity toolsStorePos) {
        return toolsStorePosDao.update(toolsStorePos);
    }

    @Override
    public int delete(String id) {
        return toolsStorePosDao.delete(id);
    }

    @Override
    public int deleteBatch(String[] ids) {
        return toolsStorePosDao.deleteBatch(ids);
    }

    @Override
    public void lockStockNum(String posId, int num) {
        /*
            获取到工装的库位信息后，
            比较下待锁定的数目是否可以，如果不可以则跑出异常
         */
        ToolsStorePosEntity pos = toolsStorePosDao.queryObject(posId);
        int storeNum = pos.getStoreNum();
        int locNum = pos.getLocNum();
        // 库位可用数目必须不小于待锁定数目
        Assert.isTrue(storeNum - locNum >= num, "可用库存不足，请更换！");
        locNum = locNum + num;
        pos.setLocNum(locNum);
        update(pos);
    }

    @Override
    public synchronized int realtimeUpdateStorePosStock(String posId) {
        // 根据库位所属的不同仓库实时计算库存数
        Integer storeType = toolsStorePosDao.getStoreHouseType(posId);
        // 获取当前库存信息
        ToolsStorePosEntity toolsStorePos = queryObject(posId);
        int storeNum = 0;
        String curMonth = null;
        if (storeType == StoreHouseType.ERP) {
            // 获取当前月份
            curMonth = com.sugon.modules.utils.DateUtil.getYearAndMonth(null);
            // 设置库存数
            storeNum = toolsStorePos.getStoreNum();
        }
        // 获取当前月份下的总入库数
        Integer totalInNum = toolsPartInService.statTotalNum(posId, curMonth);
        // 获取当前月份下的总出库数
        Integer totalOutNum = toolsPartOutService.statTotalNum(posId, curMonth);
        // 找出当前工位的退库数
        Integer totalBackNum = toolsPartBackService.statTotalNum(posId, curMonth);
        toolsStorePos.setStoreNum(storeNum + toolsStorePos.getInitNum() + totalInNum - totalOutNum + totalBackNum);
        // 找出当前库位中未出库/冻结的备件数数
        toolsStorePos.setLocNum(materialRecordDao.countUnStockOutSparePartStockNum(posId, null, null));
        return toolsStorePosDao.update(toolsStorePos);
    }

    @Override
    public ToolsStorePosEntity queryOrCreateIfNotExists(String storeId, String position, String toolsCode) {
        ToolsStorePosEntity toolsStorePos = queryByPosition(storeId, position, toolsCode);
        if (toolsStorePos == null) {
            toolsStorePos = new ToolsStorePosEntity();
            toolsStorePos.setStoreId(storeId);
            toolsStorePos.setPostion(position);
            toolsStorePos.setToolsCode(toolsCode);
            toolsStorePos.setStoreNum(0);
            toolsStorePos.setInitNum(0);
            save(toolsStorePos);
        }
        return toolsStorePos;
    }

    private ToolsStorePosEntity queryByPosition(String storeId, String position, String toolsCode) {
        Map<String, Object> param = new HashMap<>(3);
        param.put("storeId", storeId);
        param.put("postion", position);
        param.put("toolsCode", toolsCode);
        List<ToolsStorePosEntity> spareStorePosList = toolsStorePosDao.queryList(param);
        return CollectionUtil.isNotEmpty(spareStorePosList) ? spareStorePosList.get(0) : null;
    }

}
